diff options
Diffstat (limited to 'app/api/projects/[projectId]/cover/route.ts')
| -rw-r--r-- | app/api/projects/[projectId]/cover/route.ts | 78 |
1 files changed, 41 insertions, 37 deletions
diff --git a/app/api/projects/[projectId]/cover/route.ts b/app/api/projects/[projectId]/cover/route.ts index b88f06ee..802e2ab6 100644 --- a/app/api/projects/[projectId]/cover/route.ts +++ b/app/api/projects/[projectId]/cover/route.ts @@ -1,15 +1,22 @@ // app/api/projects/[projectId]/cover/route.ts import { NextRequest, NextResponse } from "next/server" -import db from "@/db/db" -import { projectCoverTemplates, generatedCoverPages } from "@/db/schema" -import { eq, and, desc } from "drizzle-orm" +import { generateCoverPage } from "@/lib/cover/cover-service" +/** + * 커버페이지 생성 및 다운로드 + * + * GET /api/projects/[projectId]/cover?docNumber=DOC-001 + * + * @param projectId - 프로젝트 ID + * @param docNumber - 문서 번호 (쿼리 파라미터) + */ export async function GET( request: NextRequest, - { params }: { params: { projectId: string } } + { params }: { params: Promise<{ projectId: string }> } ) { try { - const projectId = parseInt(params.projectId) + const { projectId: projectIdParam } = await params + const projectId = parseInt(projectIdParam) if (isNaN(projectId)) { return NextResponse.json( @@ -18,54 +25,51 @@ export async function GET( ) } - // 1. 해당 프로젝트의 활성 템플릿 찾기 - const [activeTemplate] = await db - .select() - .from(projectCoverTemplates) - .where( - and( - eq(projectCoverTemplates.projectId, projectId), - eq(projectCoverTemplates.isActive, true) - ) - ) - .limit(1) + // docNumber 쿼리 파라미터 가져오기 + const { searchParams } = new URL(request.url) + const docNumber = searchParams.get("docNumber") - if (!activeTemplate) { + if (!docNumber) { return NextResponse.json( - { success: false, message: "활성 템플릿을 찾을 수 없습니다" }, - { status: 404 } + { success: false, message: "문서 번호(docNumber)가 필요합니다" }, + { status: 400 } ) } - // 2. 해당 템플릿의 최신 생성된 커버 페이지 찾기 - const [latestCover] = await db - .select() - .from(generatedCoverPages) - .where(eq(generatedCoverPages.templateId, activeTemplate.id)) - .orderBy(desc(generatedCoverPages.generatedAt)) - .limit(1) + console.log(`📄 커버페이지 요청 - ProjectID: ${projectId}, DocNumber: ${docNumber}`) - if (!latestCover) { + // 커버페이지 생성 + const result = await generateCoverPage(projectId, docNumber) + + if (!result.success || !result.buffer) { return NextResponse.json( - { success: false, message: "생성된 커버 페이지를 찾을 수 없습니다" }, - { status: 404 } + { + success: false, + message: result.error || "커버페이지 생성 실패" + }, + { status: 500 } ) } - // 3. 파일 경로와 정보 반환 - return NextResponse.json({ - success: true, - fileUrl: latestCover.filePath, - fileName: latestCover.fileName, - generatedAt: latestCover.generatedAt, + // DOCX 파일로 응답 + // Buffer를 Uint8Array로 변환 + const uint8Array = new Uint8Array(result.buffer) + + return new NextResponse(uint8Array, { + status: 200, + headers: { + "Content-Type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "Content-Disposition": `attachment; filename="${encodeURIComponent(result.fileName || "cover.docx")}"`, + "Content-Length": result.buffer.length.toString(), + }, }) } catch (error) { - console.error("❌ 커버 페이지 조회 오류:", error) + console.error("❌ 커버 페이지 생성 오류:", error) return NextResponse.json( { success: false, - message: error instanceof Error ? error.message : "조회 중 오류 발생" + message: error instanceof Error ? error.message : "생성 중 오류 발생" }, { status: 500 } ) |
